"""
	案例:
	    电信客户流失分析.

	目的:
	    1. 演示逻辑回归的相关操作, 主要是: 二分法(流失, 不流失)
	    2. 演示逻辑回归的评估操作, 主要是: 混淆矩阵, 准确率, 召回率, F1值, ROC曲线, AUC值, 分类评估报告(了解)
	"""
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LogisticRegression
#                             准确率           精确率            召回率        F1值        roc曲线          分类评估报告
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, \
    classification_report
from sklearn.model_selection import train_test_split


# todo 1、 定义函数 ，实现数据预处理
def dm01_数据预处理():
    # 1、读取数据
    data = pd.read_csv("../data/churn.csv")
    # data.info()

    # 、2、因为上述的字段Churn、gender 是字符串类型，所以我们需要对其进行转换，对齐做one-hot编码处理
    # 底层数据是boolean值 ，布尔值和int类型直接可以转换
    data = pd.get_dummies(data)
    # data.info()
    # print(data.head())

    # 3、删除列 ，因为热编码之后，被热编码列 多出一个列 ，我们要删除掉
    data.drop(['gender_Male', 'Churn_No'], axis=1, inplace=True)
    # print(data.)
    # data.info()

    # 4、这是我们标签。修改一下标签名   Churn_Yes  flag  label
    data.rename(columns={'Churn_Yes': 'flag'}, inplace=True)
    print(data.head())

    # 5、因为这里是流失数据  查看   标签 是否均衡
    print(data.flag.value_counts())  # false ->不流失   true -》流失

    # 2. 定义函数, 用于显示: 月度会员的流失情况.


def dm03_会员流失可视化情况():
    # 1. 读取数据.
    data = pd.read_csv('../data/churn.csv')
    # 2. 对上述的数据做 热编码处理.
    data = pd.get_dummies(data)
    # 3. 删除列, 因为热编码之后, 会多出一个列, 我们删除掉.
    data.drop(['gender_Male', 'Churn_No'], axis=1, inplace=True)
    # 4. 修改列名.
    data.rename(columns={'Churn_Yes': 'flag'}, inplace=True)
    # 5. 查看数据集的分布情况.
    print(data.flag.value_counts())  # False -> 不流失, True -> 流失
    print(data.columns)  # 查看所有列名.

    # 6. 通过计数柱状图, 绘制(月度)会员的流失情况.
    # 参数x意思是: x轴的列名(是否是月度会员, 0 -> 不是会员, 1 -> 是会员)
    # 参数hue意思是: 根据hue的值, 将数据进行分类(False -> 不流失, True -> 流失)
    # sns.countplot(data)#没有传入参数 ，会打印彩色柱状
    sns.countplot(data, x='Contract_Month', hue='flag')  # 注意M大写
    plt.show()


def dm02_逻辑回归模型训练与评估():
    # 1、读取数据
    data = pd.read_csv("../data/churn.csv")
    # 2、对上述数据做热编码
    data = pd.get_dummies(data)
    # 3、删除列 &修改标签列名字
    data.drop(['gender_Male', 'Churn_No'], axis=1, inplace=True)
    data.rename(columns={'Churn_Yes': 'flag'}, inplace=True)

    # 4、获取特征列与标签列
    x = data[['Contract_Month', 'internet_other', 'PaymentElectronic']]
    # print(x.head())
    y = data['flag']

    # 5、数据预处理切分训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=22, stratify=y)

    # 6、创建逻辑回归模型 并训练
    es = LogisticRegression()
    es.fit(x_train, y_train)

    # 7、模型预测
    y_predict = es.predict(x_test)

    # 8、模型评估
    # 8.1准确率:
    print(f"准确率:{es.score(x_test, y_test)}")
    # 8.2精确率
    print(f"精确率:{precision_score(y_test, y_predict)}")
    # 8.3 召回率
    print(f"召回率:{recall_score(y_test, y_predict)}")
    # 8.4F1值
    print(f"F1值:{f1_score(y_test, y_predict)}")
    # 8.5 分类评估报告
    print(f"分类评估报告：{classification_report(y_test, y_predict)}")

    # 8.6 roc曲线   样式:[样本数,类别]  [:,0] 每个样本属于负类概率
    #                               [:,1]每个样本属于正类概率
    y_proba = es.predict_proba(x_test)[:, 1]
    print(f"roc曲线：{roc_auc_score(y_test, y_proba)}")


if __name__ == '__main__':
    # dm01_数据预处理()
    # dm02_逻辑回归模型训练与评估()
    dm03_会员流失可视化情况()